package com.hwtx.form.domain.def;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.hwtx.form.domain.FormConstants;
import com.hwtx.form.util.BeanUtil;
import io.geekidea.boot.framework.exception.BusinessException;
import io.geekidea.boot.system.vo.ProValueConfig;
import lombok.Data;
import lombok.Getter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class FormDetailExt {
    private String configTabs;
    private FormExt formExt;
    private ListExt listExt;

    public static List<FormConstants.FormConfigType> getConfigTabs(String configTabs, Long formId) {
        if (configTabs == null) {
            throw new BusinessException("未配置表单明细,formId = " + formId);
        }
        return BeanUtil.splitIntWithComma(configTabs).stream().map(FormConstants.FormConfigType::of).toList();
    }

    public enum OperationConditionType {
        count;

        public String toString() {
            return switch (this) {
                case count -> "count";
            };
        }
    }

    public enum OperationPopType {
        dialog,
        right_position,
        left_position,
        page;
    }

    @Data
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class TplConfigExt {
        private List<TplConfig> tplConfigs;
        private String action;
        private Boolean init;
    }

    @Data
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class OperationCondition {
        private OperationConfig opConfig;
        private List<ProValueConfig> opValues;
    }

    @Data
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class OperationConfig {
        private String type;
        private String operator;
        private String value;
    }

    @Data
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class FormExt {
        private Boolean formStatic;
        private Map<String, String> paramMapping;

        public boolean isEmpty() {
            return formStatic == null && MapUtils.isEmpty(paramMapping);
        }
    }

    @Data
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class ListExt {
        private List<Operation> operations;
        private Map<String, String> paramMapping;

        public boolean isEmpty() {
            return CollectionUtils.isEmpty(operations) && MapUtils.isEmpty(paramMapping);
        }
    }

    @Data
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class TplConfig {
        String title;
        Integer formConfigItem;
        String ffName;
        String ffId;
        Integer controller;
        String name;
        String desc;
        Integer detailType;

        public String getTarget() {
            return ffId + "->" + ffName;
        }

        public enum DetailInfoType {
            Controller(2),
            Page(1);
            @Getter
            private final int value;

            DetailInfoType(int value) {
                this.value = value;
            }

            public static DetailInfoType of(int value) {
                for (DetailInfoType detailInfoType : DetailInfoType.values()) {
                    if (detailInfoType.value == value) {
                        return detailInfoType;
                    }
                }
                return null;
            }
        }
    }

    @Data
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class Operation {
        private String label;
        private String apply;
        private String value;
        private boolean system;
        private String target;
        private String popType;
        private String actionChain;
        private Map<String, String> actionParams;
        private List<OperationCondition> conditions;
        private List<OperationVisible> visible;

        public boolean empty() {
            return label == null || value == null;
        }

        @JsonIgnore
        public Set<String> getApplies() {
            if (Objects.equals(value, FormConstants.OPERATION_DELETE_BULK)) {
                return Set.of(apply, FormConstants.OPERATION_HEADER_BULK);
            }
            return Set.of(apply);
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Operation operation = (Operation) o;
            return Objects.equals(label, operation.label) || Objects.equals(value, operation.value);
        }

        @Override
        public int hashCode() {
            return Objects.hash(label, value);
        }
    }

    @Data
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class OperationVisible {
        private String visibleType;
        private String visibleField;
        private String visibleExpr;
        private String visibleFieldVal;
        private String visibleFieldOp;
    }
}
